package org.nobject.common.lang;



import static org.nobject.common.lang.StringUtils.removeEnd;
import static org.nobject.common.lang.StringUtils.removeStart;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.nobject.common.exception.AmbiguousException;
import org.nobject.common.exception.HandleException;
import org.nobject.common.exception.InvokeException;
import org.nobject.common.exception.NoFoundException;
import org.nobject.common.exception.UnSupportException;
import org.nobject.common.file.FileUtils;
import org.nobject.common.js.JSONObject;
import org.nobject.common.lang.handler.FindResourceHandler;
import org.nobject.common.regex.RegexUtils;
/**
 * Class工具类<br>
 * 可以获取或设置Field、Method<br>
 * 
 * 获取时自动获得所有父类的成员及方法,但不包括Object类的成员方法,以重载的方法为主,<br>
 * 
 * 设置时遇到private和protected时进行Accessble改动,然后强行设置,如果遇到 java.permission限制可能抛出异常
 * 
 * @author bianrongjun
 * @version 1.0
 */
public class ClassUtils {
	
	/** 缓存开关 */
	public static boolean cache=true;
	
	/** cl */
	public static ClassLoader cl;
	
	/** 
	 * 加载类
	 * @param className 类名
	 */
	public static Class forName(String className) throws ClassNotFoundException{
		if(cl==null){
			cl=Thread.currentThread().getContextClassLoader();
		}
		return cl.loadClass(className);
	}
	
	/** 
	 * 获取内部类
	 * @param clazz 类
	 * @param className 类名称
	 */
	public static Class getInnerClass(Class clazz,String className){
		Class[] innerClasses=clazz.getDeclaredClasses();
		for (Class innerClass : innerClasses) if(innerClass.getSimpleName().equalsIgnoreCase(className)){
			return innerClass;
		}
		return null;
	}
	
	/** 
	 * 获取内部类s
	 * @param clazz
	 * @param className
	 */
	public static List getInnerClasses(Class clazz,String className){
		Class[] innerClasses=clazz.getDeclaredClasses();
		List cs=new LinkedList();
		for (Class innerClass : innerClasses){
			String nameRegex=className==null?null:className.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*");
			if(RegexUtils.matches(innerClass.getSimpleName(), nameRegex, true)) {
				cs.add(innerClass);
			}
		}
		return cs;
	}
	
	/******************************************************************************************************************
	 * 
	 *  Field 区域
	 * 
	 *******************************************************************************************************************/
	
	/** 
	 * 获取成员
	 * @param clazz 类
	 * @param fieldName 成员名
	 * @see #getFields0(Class, String[], Class, int[])
	 */
	public static Field getField(Class clazz,String fieldName){
		Field [] fields=getFields0(clazz,new String[]{fieldName}, null, null);
		return fields==null||fields.length==0?null:fields[0];
	}
	
	/** 
	 * 获取所有的类成员
	 * @param clazz 类
	 * 
	 * @see #getFields0(Class, String[], Class, int[])
	 */
	public static Field[] getFields(Class clazz){
		return getFields0(clazz,null,null,null);
	}
	
	/** 
	 * 获取名称匹配的类成员
	 * @param clazz 类
	 * @param fieldName 成员名称 
	 * 
	 * @see #getFields0(Class, String[], Class, int[])
	 */
	public static Field[] getFields(Class clazz,String fieldName){
		return getFields0(clazz,new String[]{fieldName}, null, null);
	}
	
	/** 
	 * 获取匹配的类成员<br>
	 * 名称支持.*模糊匹配<br>
	 * 当名称=null,成员类型=null,修饰符=null时,分别不进行过滤
	 * 
	 * @param clazz 类
	 * @param fieldName 成员名称 
	 * @param fieldType 成员类型
	 * @param modifiers 修饰符数组
	 * 
	 * @see #getFields0(Class, String[], Class, int[])
	 */
	public static Field[] getFields(Class clazz,String fieldName,Class fieldType,int[] modifiers){
		return getFields0(clazz, new String[]{fieldName}, fieldType, modifiers);
	}
	
	
	private static Map caches_getFields0=new HashMap();
	/** 
	 * 获取名称匹配的类成员<br>
	 * 名称支持.*模糊匹配<br>
	 * 当名称=null,成员类型=null,修饰符=null时,分别不进行过滤
	 * 
	 * @param clazz 类
	 * @param fieldNames 成员名称数组
	 * @param fieldType 成员类型
	 * @param modifiers 修饰符数组
	 */
	public static Field[] getFields0(Class clazz,String[] fieldNames,Class fieldType,int[] modifiers){
		String _k=null; 
		if(cache){
			_k=StringUtils.toString(new Object[]{clazz,fieldNames,fieldType,modifiers});
			if(caches_getFields0.containsKey(_k)) {return (Field[])caches_getFields0.get(_k);}
		}
		
		Set<Field> fs=new LinkedHashSet();
		Set ks=new LinkedHashSet();
		do{
			Field [] fields=clazz.getDeclaredFields();
			for (Field f:fields) {
				if(ks.contains(f.getName())) continue;
				//名称
				if(fieldNames!=null&&fieldNames.length>0){
					boolean match=false;
					for(String fieldName:fieldNames){
						String fieldNameRegex=fieldName==null?".*":fieldName.replaceAll("\\$", "\\\\\\$").replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*");
						if(f.getName().matches(fieldNameRegex)) {match=true;break;}
					}
					if(!match)continue;
				}
				//参数类型:判定实际参数类型是否为指定参数类型的等价类型
				if(fieldType!=null&&!isEqualImpl(fieldType,f.getType())) continue;
				//修饰符
				if(modifiers!=null&&!matchModifiers(modifiers)) continue;
				fs.add(f);
				ks.add(f.getName());
			}
		}while((clazz=clazz.getSuperclass())!=null&&!clazz.equals(Object.class));
		
		Field[] _fs=(Field[])ArrayUtils.toArray(fs, Field.class);
		
		if(cache){
			caches_getFields0.put(_k, _fs);
		}
		
		return _fs;
	}
	
	/** 
	 * 强行获取所有的成员（包括私有）
	 * @param clazz
	 */
	public static Field [] getFieldsForce(Class clazz){
		try {
			Method m = Class.class.getDeclaredMethod("getDeclaredFields0", new Class[]{boolean.class});
			m.setAccessible(true);
	        Field[] fs=(Field[])m.invoke(clazz,new Object[]{false});
	        return fs;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/** 
	 * 强行获取制定的成员（包括私有）
	 * @param clazz
	 * @param fieldName
	 */
	public static Field getFieldForce(Class clazz,String fieldName){
		return getFieldForce(clazz, fieldName, true);
	}
	
	/** 
	 * 强行获取制定的成员（包括私有）
	 * @param clazz
	 * @param fieldName
	 */
	public static Field getFieldForce(Class clazz,String fieldName,boolean autoSetAccess){
		Field[] fs=getFieldsForce(clazz);
		for(Field f:fs){
			if(f.getName().equals(fieldName)){
				if(autoSetAccess) f.setAccessible(true);
				return f;
			}
		}
		return null;
	}
	
	/** 
	 * 设置成员
	 * @param obj 实例
	 * @param field 成员
	 * @param fieldValue 成员值
	 * 
	 * @throws UnSupportException
	 * @throws InvokeException
	 */
	public static void setField(Object obj,String fieldName, Object fieldValue) throws NoFoundException,InvokeException,UnSupportException{
		Field f=getField(obj.getClass(), fieldName);
		if(f==null) throw new NoFoundException("未找到成员"+obj.getClass().getName()+"#"+fieldName);
		setField(obj, f, fieldValue);
	}
	
	/** 
	 * 设置类静成员值<br>
	 * 当实例为null时，只能设置静态成员值否则会发生异常
	 * @param obj 实例
	 * @param field 成员
	 * @param fieldValue 成员值
	 * 
	 * @throws UnSupportException 实例为null时设置非静态成员引发的异常
	 * @throws InvokeException Field.set时引起的异常
	 */
	public static void setField(Object obj,Field field, Object fieldValue) throws UnSupportException,InvokeException{
		if(!field.isAccessible()) field.setAccessible(true);
		if(obj==null&&!Modifier.isStatic(field.getModifiers())) throw new UnSupportException("非静态成员"+field.getDeclaringClass().getName()+"#"+field.getName()+"不能静态方式设置");
		try {
			field.set(obj, fieldValue);
		} catch (Exception e) {
			throw new InvokeException(e.getMessage());
		}
	}
	
	/** 
	 * 设置类静态成员值
	 * @param clazz 静态类
	 * @param fieldName 成员名
	 * @param fieldValue 成员值
	 * 
	 * @throws InvokeException Field.set时引起的异常
	 * @throws NoFoundException 因没有发现成员变量而发生的异常
	 * @throws UnSupportException 实例为null但参数非静态时引发的异常
	 */
	public static void setStaticField(Class clazz, String fieldName, Object fieldValue) throws UnSupportException,InvokeException,NoFoundException{
		Field f=getField(clazz, fieldName);
		if(f==null) throw new NoFoundException("未找到成员"+clazz.getName()+"#"+fieldName);
		setField(null, f, fieldValue);
	}
	
	/** 
	 * 设置成员值
	 * @param obj实例
	 * @param fieldValues 成员值Map
	 * 
	 * @throws InvokeException Field.set时引起的异常
	 * @throws UnSupportException 实例为null但参数非静态时引发的异常
	 * 
	 * @see #setFields(Object, Class, Map)
	 */
	public static void setFields(Object obj,Map fieldValues) throws UnSupportException,InvokeException{
		setFields(obj,obj.getClass(),fieldValues);
	}
	
	/** 
	 * 设置静态成员值
	 * @param clazz 类
	 * @param fieldValues 成员值Map
	 * 
	 * @throws InvokeException Field.set时引起的异常
	 * @throws UnSupportException 实例为null但参数非静态时引发的异常
	 * 
	 * @see #setFields(Object, Class, Map)
	 */
	public static void setStaticFields(Class clazz, Map fieldValues) throws InvokeException,UnSupportException{
		setFields(null,clazz,fieldValues);
	}
	
	/** 
	 * 设置成员值<br>
	 * 忽略不存在的键值
	 * @param obj 实例
	 * @param clazz 类
	 * @param fieldValues 成员值Map
	 * 
	 * @throws InvokeException Field.set时引起的异常
	 * @throws UnSupportException 实例为null但参数非静态时引发的异常
	 */
	public static void setFields(Object obj,Class clazz,Map fieldValues) throws UnSupportException,InvokeException{
		Field [] fs=getFields(clazz);
		for (Iterator iterator = fieldValues.keySet().iterator(); iterator.hasNext();) {
			String fName = (String)iterator.next();
			Object fValue = fieldValues.get(fName);
			for(Field f:fs){
				if(f.getName().equals(fName)){
					setField(obj, f, fValue);
				}
			}
		}
	}
	
	/** 
	 * 获取类成员值
	 * @param obj 类实例
	 * @param fieldName 成员名
	 * 
	 * @throws InvokeException Field.get时引起的异常
	 * @throws NoFoundException 因没有发现成员变量而发生的异常
	 */
	public static Object getFieldValue(Object obj,String fieldName) throws InvokeException,NoFoundException{
		Field f=getField(obj.getClass(), fieldName);
		if(f==null) throw new NoFoundException(obj.getClass().getName()+" 未找到成员"+fieldName);
		if(!f.isAccessible()) f.setAccessible(true);
		try {
			return f.get(obj);
		} catch (Exception e) {
			throw new InvokeException(e.getMessage());
		}
	}
	
	/** 
	 * 获取静态成员值
	 * @param clazz 类
	 * @param fieldName 成员名
	 * @return
	 * @throws InvokeException
	 * @throws NoFoundException
	 */
	public static Object getStaticFieldValue(Class clazz,String fieldName) throws InvokeException,NoFoundException{
		Field f=getField(clazz, fieldName);
		if(f==null) throw new NoFoundException(clazz.getName()+" 未找到成员"+fieldName);
		if(!f.isAccessible()) f.setAccessible(true);
		try {
			return f.get(null);
		} catch (Exception e) {
			throw new InvokeException(e.getMessage());
		}
	}
	
	/**
	 * 获取成员类
	 * @param clazz 类
	 * @param fieldName 成员名
	 * @throws NoFoundException 因没有发现成员变量而发生的异常
	 */
	public static Class getFieldClass(Class clazz, String fieldName) throws NoFoundException{
		Field f=getField(clazz, fieldName);
		if(f==null) throw new NoFoundException(clazz.getName()+" 未找到成员"+fieldName);
		return f.getType();
	}

	
	
	
	/******************************************************************************************************************
	 * 
	 *  Method 区域
	 * 
	 *******************************************************************************************************************/
	
//	/** 
//	 * 获取方法的描述
//	 * @param method 方法
//	 */
//	public static String getMethodDesc(Method method){
//		StringBuffer p=new StringBuffer();
//		
//		Class [] cls=method.getParameterTypes();
//		for (int i = 0; i < cls.length; i++) {
//			if(i!=0) p.append(",");
//			p.append(cls[i].getName());
//		}
//		
//		return method.getName()+"("+p+")";
//	}
	
	/** 
	 * 查找Method
	 * @param methodDesc 方法描述符
	 */
	public static Method getMethod(String methodDesc) throws ClassNotFoundException,AmbiguousException{
		boolean ignore=false;
		if(methodDesc.indexOf("(")<0){
			ignore=true;
			methodDesc+="()";
		}
		
		String className=methodDesc.substring(0, methodDesc.indexOf("#"));
		String methodName=methodDesc.substring(methodDesc.indexOf("#")+1,methodDesc.indexOf("("));
		Class c=forName(className);
		if(!ignore){
			String[] strParams=methodDesc.substring(methodDesc.indexOf("(")+1,methodDesc.length()-1).split(",");
			Class[] pts=new Class[strParams.length];
			for (int i = 0; i < strParams.length; i++) {
				pts[i]=forName(strParams[i]);
			}
			return getMethod(c, methodName, pts);
		}else{
			return getMethod(c, methodName);
		}
	}
//	
//	public static void main(String[] args) throws Exception{
//		
//		String methodDesc="org.nobject.common.lang.ClassUtils#getMethod(java.lang.String)";
//		
//		System.out.println(getMethod(methodDesc).getName());
//	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, -1, null, null,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param ignoreCase 忽略大小写
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,boolean ignoreCase) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, -1, null, null,ignoreCase);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param modifiers 修饰符组
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,int[] modifiers) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, -1, null, modifiers,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,Class[] paramTypes) throws AmbiguousException{
		return getMethod0(clazz, methodName,paramTypes, -1, null, null,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 * @param modifiers 修饰符组
	 * 
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,Class[] paramTypes,int[] modifiers) throws AmbiguousException{
		return getMethod0(clazz, methodName,paramTypes, -1, null, null,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramsCount 参数数量
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,int paramsCount) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, paramsCount, null, null,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramsCount 参数数量
	 * @param ignoreCase 忽略大小写
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,int paramsCount,boolean ignoreCase) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, paramsCount, null, null,ignoreCase);
	}
	
	/** 
	 * 获取唯一的方法
	 * 
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramsCount 参数数量
	 * @param modifiers 修饰符组
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,int paramsCount,int[] modifiers) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, paramsCount, null,modifiers,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramsCount 参数数量
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 * 
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,int paramsCount,Class returnType,int[] modifiers) throws AmbiguousException{
		return getMethod0(clazz, methodName,null, paramsCount, returnType, modifiers,false);
	}
	
	/** 
	 * 获取唯一的方法
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 * 
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod(Class clazz,String methodName,Class[] paramTypes,Class returnType,int[] modifiers) throws AmbiguousException{
		return getMethod0(clazz, methodName,paramTypes, -1, returnType, modifiers,false);
	}
	
	/** 
	 * getMethod0
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 * @param paramsCount 参数数量
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod0(Class clazz,String methodName,Class[] paramTypes,int paramsCount,Class returnType,int[] modifiers) throws AmbiguousException{
		return getMethod0(clazz, methodName, paramTypes, paramsCount, returnType, modifiers,false);
	}
	
	/** 
	 * getMethod0
	 * @param clazz 类
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 * @param paramsCount 参数数量
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 * @param ignoreCase 忽略大小写
	 *
	 * @throws AmbiguousException 多个方法无法识时引起异常
	 */
	public static Method getMethod0(Class clazz,String methodName,Class[] paramTypes,int paramsCount,Class returnType,int[] modifiers,boolean ignoreCase) throws AmbiguousException{
		Method [] methods=getMethods0(clazz, new String[]{methodName}, paramTypes,paramsCount, returnType, modifiers,ignoreCase);
		if(methods.length>1) throw new AmbiguousException("无法识别"+clazz.getName()+"#"+methodName+"多个方法");
		return methods==null||methods.length==0?null:methods[0];
	}
	
	
	/** 
	 * 获取所有的类方法集合
	 * @param clazz 类
	 * 
	 * @see #getMethods0(Class, String[], Class[], int, Class, int[])
	 */
	public static Method[] getMethods(Class clazz){
		return getMethods0(clazz, null,null,-1,null,null);
	}
	
	/** 
	 * 获取匹配的类方法集合
	 * 
	 * @param clazz 类 
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 * @param returnType 返回类型
	 * 
	 * @see #getMethods(Class, String, Class[], int, Class, int[])
	 */
	public static Method[] getMethods(Class clazz,String methodName,Class[] paramTypes,Class returnType){
		return getMethods(clazz, methodName, paramTypes, -1, returnType,null) ;
	}
	
	/** 
	 * 获取匹配的类方法集合
	 * 
	 * @param clazz 类 
	 * @param methodName 方法名
	 * @param paramTypes 参数类型
	 * @param modifiers 修饰符
	 * 
	 * @see #getMethods(Class, String, Class[], int, Class, int[])
	 */
	public static Method[] getMethods(Class clazz,String methodName,Class[] paramTypes,int[] modifiers){
		return getMethods(clazz, methodName, paramTypes,-1, null,modifiers) ;
	}
	
	/** 
	 * 获取匹配的类方法集合<br>
	 * 包括父类方法但不包括Object类方法<br>
	 * 名称支持.*模糊匹配<br>
	 * 名称=null,参数类型=null,返回类型==null,参数个数<0时,不进行对应的过滤,
	 * 
	 * @param clazz 类 
	 * @param methodNames 方法名
	 * @param paramTypes 参数类型
	 * @param paramsCount 参数个数
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 * 
	 * @see #getMethods0(Class, String[], Class[], int, Class, int[])
	 */
	public static Method[] getMethods(Class clazz,String methodName,Class[] paramTypes,int paramsCount,Class returnType,int[] modifiers){
		return getMethods0(clazz, new String[]{methodName}, paramTypes, paramsCount, returnType, modifiers);
	}
	
	/** 
	 * 获取匹配的类方法集合<br>
	 * 包括父类方法但不包括Object类方法<br>
	 * 名称支持.*模糊匹配<br>
	 * 名称=null,参数类型=null,返回类型==null,参数个数<0时,不进行对应的过滤,
	 * 
	 * @param clazz 类 
	 * @param methodName 方法名组
	 * @param paramTypes 参数类型
	 * @param paramsCount 参数个数
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 */
	public static Method[] getMethods0(Class clazz,String[] methodNames,Class[] paramTypes,int paramsCount,Class returnType,int[] modifiers){
		return getMethods0(clazz, methodNames, paramTypes, paramsCount, returnType, modifiers, false);
	}
	
	
	
	private static Map caches_getMethods0=new HashMap();
	
	
	/** 
	 * 获取匹配的类方法集合<br>
	 * 包括父类方法但不包括Object类方法<br>
	 * 名称支持.*模糊匹配<br>
	 * 名称=null,参数类型=null,返回类型==null,参数个数<0时,不进行对应的过滤,
	 * 
	 * @param clazz 类 
	 * @param methodName 方法名组
	 * @param paramTypes 参数类型
	 * @param paramsCount 参数个数
	 * @param returnType 返回类型
	 * @param modifiers 修饰符组
	 * @param ignoreCase 忽略大小写
	 */
	public static Method[] getMethods0(Class clazz,String[] methodNames,Class[] paramTypes,int paramsCount,Class returnType,int[] modifiers,boolean ignoreCase){
		String _k=null;
		if(cache){
			_k=StringUtils.toString(new Object[]{clazz,methodNames,paramTypes,paramsCount,returnType,modifiers,ignoreCase});
			if(caches_getMethods0.containsKey(_k)) {return (Method[])caches_getMethods0.get(_k);}
		}
		
		Set<Method> ms=new LinkedHashSet();
		Set ks=new LinkedHashSet();
		do{
			Method [] methods=clazz.getDeclaredMethods();
			for (Method m:methods) {
				Class[] pts=m.getParameterTypes();
				String k=m.getName()+"#"+StringUtils.toString(pts);
				if(ks.contains(k)) continue;
				//名称
				if(methodNames!=null&&methodNames.length>0){
					boolean match=false;
					for(String methodName:methodNames){
						String methodNameRegex=methodName==null?null:methodName.replaceAll("\\$", "\\\\\\$").replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*");
						if(RegexUtils.matches(m.getName(), methodNameRegex, ignoreCase)) {match=true;break;}
					}
					if(!match)continue;
				}
				//参数类型:判定实际参数类型组是否为指定参数类型的等价类型
				if(paramTypes!=null&&!isEqualImpl(paramTypes,pts)) continue;
				//参数个数:判定实际参数个数组是否为指定参数类型个数
				if(paramsCount>=0&pts.length!=paramsCount) continue;
				//修饰符:判定实际方法修饰符是否匹配
				if(modifiers!=null&&!matchModifiers(modifiers)) continue;
				//返回值:判定实际返回类型组不是否为指定返回类型的等价类型
				if(returnType!=null&&!isEqualImpl(m.getReturnType(),returnType)) continue;
				
				ms.add(m);
				ks.add(k.toString());
			}
		}while((clazz=clazz.getSuperclass())!=null&&!clazz.equals(Object.class));
		
		Method[] m=(Method[])ArrayUtils.toArray(ms,Method.class);
		
		if(cache){
			caches_getMethods0.put(_k, m);
		}
		
		return  m;
	}
	
	/******************************************************************************************************************
	 * 
	 *  Constructor 区域
	 * 
	 *******************************************************************************************************************/	
	
	/** 
	 * 获取构造函数<br>
	 * 可自动找到相同性质的构造函数:基本类型与包装类<br>
	 * 传入接口、父类，可找分别到实现类和子类为参数的构造函数
	 * 
	 * @param clazz 类
	 * @param paramTypes 构造函数参数组
	 */
	public static Constructor getConstructor(Class clazz,Class[] paramTypes){
		if(paramTypes==null) paramTypes=new Class[]{};
		Constructor[] cs=clazz.getConstructors();
		for(Constructor c:cs) if((isEqualImpl(paramTypes,c.getParameterTypes()))) return c;
		return null;
	}
	
	/** 
	 * 获取对象数组对应的类数组
	 * @param objs 对象数组
	 */
	public static Class[] getClassesByObjs(Object... objs){
		if(objs==null) return null;
		Class [] classes=new Class[objs.length];
		for (int i = 0; i < classes.length; i++) classes[i]=objs[i].getClass();
		return classes;
	}
	
	/** 
	 * 根据名称数组获取Class数组
	 * @param classNames 类名称数组
	 * @throws ClassNotFoundException @see {@link java.lang.Class#forName(String)}
	 */
	public static Class[] getClassesByNames(String[] classNames) throws ClassNotFoundException{
		Class[] classes=new Class[classNames.length];
		for (int i = 0; i < classNames.length; i++) classes[i]=Class.forName(classNames[i]);
		return classes;
	}
	
	/** 
	 * 获取类数组的名称数组
	 * @param classes 类数组
	 */
	public static String[] getClassNames(Class[] classes){
		String [] classNames=new String[classes.length];
		for (int i = 0; i < classNames.length; i++) classNames[i]=classes[i].getName();
		return classNames;
	}
	
	/** 
	 * 获取指定类中的转换方法。名为to+转换类型的简称,返回类型为转换类型
	 * @param clazz 类
	 * @param toType 转换类型
	 */
	public static Method getToMethod(Class clazz,Class toType){
		String simpleName=toSimpleName(toType.getName());
		try {
			return getMethod(clazz, "to"+simpleName,0,toType,new int[]{Modifier.PUBLIC});
		} catch (AmbiguousException e) {
			throw new RuntimeException(e);//同名方法无参只能有一个=>不可能发生
		}
	}
	
	/** 
	 * 将类全名转换成去除包名后的简名
	 * @param className 全名
	 */
	public static String toSimpleName(String className){
		return className.substring(className.lastIndexOf(".")+1);
	}	
	
	
	/** nicktypes */
	public static Map nicktypes=MapUtils.toMap(new Object[][]{
			{"string"	,String.class},
			{"int"		,int.class},
			{"long"		,long.class},
			{"boolean"	,boolean.class},
			{"double"	,double.class},
			{"float"	,float.class},
			{"char"		,char.class},
			{"byte"		,byte.class},
			{"date"		,Date.class},
			{"map"		,Map.class},
			{"list"		,List.class},
			{"object"	,Object.class},
			{"jsonobject",JSONObject.class},
			{"jsonarray",JSONObject.class}
	});
	
	/**
	 * 获取昵称对应类(支持数组)
	 * 别名参照nicktypes列表
	 * @param nicktype 类昵称
	 */
	public static Class getClassByNicktype(String nicktype) throws ClassNotFoundException{
		boolean isArray=false;
		if(nicktype.endsWith("[]")){
			isArray=true;
			nicktype=nicktype.substring(0,nicktype.length()-2);
		}
		
		Class clazz=null;
		if(nicktypes.containsKey(nicktype)) clazz=(Class)nicktypes.get(nicktype);
		
		if(clazz==null)	clazz=Class.forName(nicktype);
		if(isArray){
			Object o=Array.newInstance(clazz, 1);
			clazz=o.getClass();
			o=null;
		}
		return clazz;
		
	}
	
	
	/** 封装类 */
	private static Class[] encapClasses=new Class[]{Integer.class,Long.class,Double.class,Float.class,Boolean.class,Byte.class,Character.class,Short.class};
	
	/**
	 * 获取基础数据类型的封装类
	 * @param clazz 类
	 * @return 返回基础数据类型的封装类，其它类则返回null
	 */
	public static Class getEncapClass(Class clazz) {
		if (clazz.isPrimitive()) {
			for(Class encapClass:encapClasses){
				try {
					if(encapClass.getField("TYPE").get(null).equals(clazz)) return encapClass;
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		}
		return null;
	}
	
	/**
	 * 获取类集成来具有的所有接口以及接口实现的接口
	 * @param clazz 类
	 */
	public static Set getInterfaces(Class clazz){
		Set is=new HashSet();
		while(clazz!=null){
			if(clazz.isInterface()) is.add(clazz);
			Class [] cis=clazz.getInterfaces();
			if(cis!=null&&cis.length>0) {
				for (int i = 0; i < cis.length; i++) {
					is.add(cis[i]);
					Set ics=getInterfaces(cis[i]);
					if(ics!=null&&ics.size()>0) is.addAll(ics);
				}
			}
			clazz=clazz.getSuperclass();
			if(clazz==null) return is;
		}
		return is;
	}
	
	/** 
	 * 是否同时符合多个修饰符
	 * @param modifiers 修饰符数组
	 */
	public static boolean matchModifiers(int... modifiers){
		for(int modifier:modifiers) {if(!matchModifier(modifier)) return false;}
		return true;
	}

	/** 
	 * 是否符合修饰符
	 * @param modifier 修饰符 (java.lang.reflect.Modifier)
	 */
	public static boolean matchModifier(int modifier){
		return Modifier.isPublic(modifier)
			||Modifier.isPrivate(modifier)	
			||Modifier.isStatic(modifier)
			||Modifier.isFinal(modifier)
			||Modifier.isProtected(modifier)
			||Modifier.isAbstract(modifier)
			||Modifier.isInterface(modifier)
			||Modifier.isNative(modifier)
			||Modifier.isStrict(modifier)
			||Modifier.isTransient(modifier)
			||Modifier.isVolatile(modifier);
	}
	
	
	
	/** 获取当前线程的ClassLoader及其上级所有ClassLoader,按照加载顺序 */
	public static Set getClassLoaders(){
		Set<ClassLoader> loaders=new LinkedHashSet();
		ClassLoader ld=Thread.currentThread().getContextClassLoader();
		loaders.add(ld);
		while((ld=ld.getParent())!=null) loaders.add(ld);
		return loaders;
	}
	
	
	
	
	/** 
	 * 获取类匹式的Regex
	 * 
	 * 
	 * \*\*\/表示任意目录层
	 * \* 表示非.的任意名字
	 * 
	 * @param classpath 类匹配式
	 */
	public static String getClasspathRegex(String classpath){
		return classpath=classpath
				.replaceAll("(\\*\\*/)", "@")
				.replaceAll("\\.", "\\\\.")
				.replaceAll("\\*","[^/]*")
				.replaceAll("@", ".*")
				.replaceAll("\\$", "\\\\\\$")
		;
	}
	
	/** 
	 * 获取包名
	 * 
	 * 可以获取到除了抽象表达式以上具体的包路径
	 * EXP:
	 * \\/org\\/\\*\\*\\/\\*Utils.class					=>\\/org
	 * \\/nobject\\/common\\/lang\\/StringUtils.class	=>\\/nobject\\/common\\/lang
	 * @param classpath 类匹配式
	 */
	public static String getPackagepath(String classpath){
		String packagepath=classpath;
		int c;
		if((c=classpath.indexOf("*"))>0) 			packagepath=packagepath.substring(0, packagepath.substring(0,c).lastIndexOf("/"));
		else if(c==0) 								return "/";
		else if((c=classpath.lastIndexOf("/"))>0) 	packagepath=packagepath.substring(0, c);
		return packagepath;
	}
	
//	public static void main(String[] args) throws Exception{
////		String classpath="/org/nobject/common/lang/*Utils.class";
////		String classpath="/org/**/StringUtils.class";
//		String classpath="/org/**/*Utils.*";
//		String classpathRegex=getClasspathRegex(classpath);
//		System.out.println("classpathRegex:"+classpathRegex);
//		String packageName=getPackagePath(classpath);
//		System.out.println("packageName:"+packageName);
//		findResource(classpath, new FindResourceHandler(){
//			public void handleJar(String className, JarFile jar, JarEntry jarEntry) {System.out.println("jar:"+className);}
//			public void handleFile(String className, String filePath) {System.out.println("file:"+className);}
//		});
//		System.out.println("OVER");
//	}
	
	/** 
	 * 资源名称转成类名(只对类资源有效)
	 * EXP:
	 * \\/org\\/nobject\\/common\\/lang\\/StringUtils.class => org.nobject.common.lang.StringUtils
	 * 
	 * @param resName
	 */
	public static String resName2ClassName(String resName){
		return removeEnd(removeStart(resName, "/").replaceAll("/","."),".class");
	}
	
//	/** 
//	 * 资源路径转换为资源名称
//	 * EXP:
//	 * /org/nobject/common/lang/ClassUtils.class=>org.nobject.common.lang.ClassUtils.class
//	 * @param resourceName
//	 * @return
//	 */
//	public static String resourcePath2ResourceName(String resourceName){
//		
//	}
	
	/** 
	 * 读取资源文本
	 * @param classpath 路径
	 */
	public static String readResouceText(String classpath) throws NoFoundException {
		Set<ClassLoader> loaders=getClassLoaders();
		for(ClassLoader loader:loaders){
			InputStream is=loader.getResourceAsStream(classpath);
			if(is==null) continue;
			return IOUtils.getString(is);
		}
		throw new NoFoundException("未找到资源:"+classpath);
	}
	
	/** 
	 * 读取路径下的资源
	 * 支持匹配 
	 * @param classpathPattern  类匹配式
	 * @param handler 处理器
	 * @throws HandleException
	 */
	public static void findResource(String classpath,FindResourceHandler handler) throws HandleException{
		String classpathRegex=classpath==null?null:getClasspathRegex(classpath);
		String packageName=getPackagepath(classpath);
		String packagePath=removeStart(packageName.replaceAll("\\.", "/"), "/") ;
		Set<ClassLoader> loaders=getClassLoaders();
		try {
			for(ClassLoader loader:loaders){
				Enumeration<URL> dirs = loader.getResources(packagePath);
				while (dirs.hasMoreElements()) {
					URL url = dirs.nextElement();
					if ("jar".equals(url.getProtocol())) {
						URLConnection connection = url.openConnection();
						if(!(connection instanceof JarURLConnection)) continue;
						JarFile jar=((JarURLConnection) connection).getJarFile();
						for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
							JarEntry jarEntry=(JarEntry)e.nextElement();
							if(jarEntry.isDirectory()) continue;
							String resName=removeEnd(jarEntry.getName().replaceAll("[\\\\/]", "."), ".class");
							if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
							handler.handleJar(resName,jar,jarEntry);
						}
						continue;
					}else if ("file".equals(url.getProtocol())) {
						File dir=new File(url.getPath());
						if(!dir.exists()) continue;
						int pl=dir.getPath().length();
						Set<String> files=FileUtils.getSubFilePathes(dir.getAbsolutePath(),null, true);
						for (String path:files) {
							String resName=packageName+path.substring(pl).replaceAll("\\\\", "/");
							if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
							handler.handleFile(resName,path);
						}
					}
				}
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
//TODO
//	
//	public static Set getResNamesByClasspath(String classpath) {
//		String ext=FileUtils.getFileExtension(classpath);
//		//if(ext)
//	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(Date.class.isAssignableFrom(java.sql.Timestamp.class));
//		File f=new File("file:/D:/SOU_HOME/TOMCAT_HOME/Tomcat 6.0/lib/");
//		System.out.println(f.exists());
	}
	
	/** 
	 * 获取资源的名称
	 * @param classpath
	 * @return
	 */
	public static Set getResNamesByClasspath(String classpath,String ext) {
		//类路径正则
		String classpathRegex	=classpath==null?null:getClasspathRegex(classpath);
		//包路径
		String packagePath		=getPackagepath(classpath);
		//包名
		String packageName		=removeStart(packagePath.replaceAll("\\.", "/"), "/") ;
		
		Set<ClassLoader> loaders=getClassLoaders();
		Set<String> resNames = new LinkedHashSet();
		try {
			for(ClassLoader loader:loaders){
				Enumeration<URL> dirs = loader.getResources(packageName);
				while (dirs.hasMoreElements()) {
					URL url = dirs.nextElement();
					if ("jar".equals(url.getProtocol())) {
						URLConnection connection = url.openConnection();
						if(!(connection instanceof JarURLConnection)) continue;
						JarFile jar=((JarURLConnection) connection).getJarFile();
						for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
							JarEntry jarEntry=(JarEntry)e.nextElement();
							if(jarEntry.isDirectory()) continue;
							String resName=removeEnd(jarEntry.getName().replaceAll("[\\\\/]", "."), "."+ext);
							if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
							resNames.add(resName);
						}
						continue;
					}else if ("file".equals(url.getProtocol())) {
						File dir=new File(FileUtils.getPath(url));//URIUtils.toFile(url.getF);
						if(!dir.exists()) continue;
						int pl=dir.getPath().length();
						Set<String> files=FileUtils.getSubFilePathes(dir.getAbsolutePath(),null, true);
						for (String path:files) {
							String resName=packagePath+path.substring(pl).replaceAll("\\\\", "/");
							if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
							resNames.add(resName);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return resNames;
	}
	
	/** 
	 * 
	 * @param dirPath
	 * @param classpath
	 * @return
	 */
	public static Set getClassNamesByFilepath(String classpath,String dirPath){
		File dir=new File(dirPath);
		if(!dir.exists()) return null;
		
		Set classNames=new HashSet();
		Set<String> files=FileUtils.getSubFilePathes(dir.getAbsolutePath(),null, true);
		int pl=dir.getPath().length();
		String classpathRegex	=classpath==null?null:getClasspathRegex(classpath);
		for (String path:files) {
			String resName=path.substring(pl).replaceAll("\\\\", "/");
			if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
			classNames.add(resName2ClassName(resName));
		}
		return classNames;
	}
	
	/** 
	 * getClassNamesByJarFile
	 * @param classpath
	 * @param jar
	 */
	public static Set getClassNamesByJarFile(String classpath,JarFile jar){
		Set<String> classNames = new LinkedHashSet();
		String classpathRegex	=classpath==null?null:getClasspathRegex(classpath);
		for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
			JarEntry jarEntry=(JarEntry)e.nextElement();
			if(jarEntry.isDirectory()) continue;
			String resName=removeEnd(jarEntry.getName().replaceAll("[\\\\/]", "."), ".class");
			if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
			classNames.add(resName2ClassName(resName));
		}
		return classNames;
	}
	
	/** 
	 * 根据类路径获取类名集合
	 * @param classpath 类路径
	 */
	public static Set getClassNamesByClasspath(String classpath) {
		String classpathRegex	=classpath==null?null:getClasspathRegex(classpath);
		String packageName		=getPackagepath(classpath);
		String packagePath		=removeStart(packageName.replaceAll("\\.", "/"), "/") ;
		
		Set<ClassLoader> loaders=getClassLoaders();
		Set<String> classNames = new LinkedHashSet();
		try {
			for(ClassLoader loader:loaders){
				Enumeration<URL> dirs = loader.getResources(packagePath);
				while (dirs.hasMoreElements()) {
					URL url = dirs.nextElement();
					if ("jar".equals(url.getProtocol())) {
						URLConnection connection = url.openConnection();
						if(!(connection instanceof JarURLConnection)) continue;
						JarFile jar=((JarURLConnection) connection).getJarFile();
						for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
							JarEntry jarEntry=(JarEntry)e.nextElement();
							if(jarEntry.isDirectory()) continue;
							String resName=removeEnd(jarEntry.getName().replaceAll("[\\\\/]", "."), ".class");
							if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
							classNames.add(resName2ClassName(resName));
						}
						continue;
					}else if ("file".equals(url.getProtocol())) {
						File dir=new File(FileUtils.getPath(url));
						if(!dir.exists()) continue;
						int pl=dir.getPath().length();
						Set<String> files=FileUtils.getSubFilePathes(dir.getAbsolutePath(),null, true);
						for (String path:files) {
							String resName=packageName+path.substring(pl).replaceAll("\\\\", "/");
							if(classpathRegex!=null&&!resName.matches(classpathRegex)) continue;
							classNames.add(resName2ClassName(resName));
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return classNames;
	}
	
	/** 
	 * 获取包名根据类名
	 * @param className 类名
	 */
	public static String getPackageNameByClassName(String className){
		int i;
		return (i=className.lastIndexOf("."))>=0?className.substring(0,i):null;
	}
	
	/** 
	 * 获取类包名下所有类名,可识别所有ClassLoader能识别路径下的类
	 * @param packageName 类包名
	 * 
	 */
	public static Set getClassNamesByPackageName(String packageName){
		String classpath="/"+packageName.replaceAll("\\.","/")+"/**/*.class";
		return getClassNamesByClasspath(classpath);
	}
	
	/** 
	 * 是否两个类相等,会进行封装的判断
	 * @param c1
	 * @param c2
	 * @return 如果其中一个是另一个封装类的封装类,返回true
	 */
	public static boolean isEqual(Class c1,Class c2){
		if(c1.equals(c2)) return true;
		return c1.isPrimitive() && getEncapClass(c1).equals(c2)||c2.isPrimitive()&& getEncapClass(c2).equals(c1);
	}
	
	/** 
	 * 判断A类型为B类型的等价实体类 <br>
	 * A，B是若同类、有一个是基本数据类型另外一个为其封装类、A是B的实现类或实现接口时返回真
	 * @param a 类型A
	 * @param b 类型B
	 */
	public static boolean isEqualImpl(Class a,Class b){
		if(a.isArray()!=b.isArray()) return false;
		if(a.isArray()){
			return isEqualImpl(a.getComponentType(),b.getComponentType());
		}
		return (isEqual(a, b)||b.isAssignableFrom(a));
	}
	
	/** 
	 * 判断A类型组为B类型组的等价实体类型组
	 * @param a A类型组
	 * @param b B类型组
	 */
	public static boolean isEqualImpl(Class[] a,Class[] b){
		if(a.length!=b.length) return false;
		for(int i=0;i<a.length;i++){
			if(!isEqualImpl(a[i], b[i])) return false;
		}
		return true;
	}
	
	/** 
	 * 方法执行
	 * @param o 对象
	 * @param m 方法
	 */
	public static Object invoke(Object o,Method m) throws InvokeException{
		return invoke(o,m,new Object[]{});
	}
	
	/** 
	 * 方法执行
	 * @param o 对象
	 * @param m 方法
	 * @param params 参数
	 */
	public static Object invoke(Object o,Method m,Object[] params) throws InvokeException{
		try {
			return m.invoke(o, params);
		} catch (Exception e) {
			throw new InvokeException(e);
		}
	}
	
	/** 是否为Class类型 */
	public static boolean isClass(Class clazz)		{return clazz.equals(Class.class);}
	/** 是否为String类型 */
	public static boolean isString(Class clazz)		{return clazz.equals(String.class);}
	/** 是否为char类型 */
	public static boolean isChar(Class clazz)		{return (clazz.equals(char.class)||clazz.equals(Character.class));}
	//NUMBER 
	/** 是否为数字类型 */
	public static boolean isNumber(Class clazz)		{return Number.class.isAssignableFrom(clazz)||isInt(clazz)||isLong(clazz)||isDouble(clazz)||isByte(clazz)||isFloat(clazz)||isShort(clazz);}
	/** 是否为byte类型 */
	public static boolean isByte(Class clazz)		{return (clazz.equals(byte.class)||clazz.equals(Byte.class));}
	/** 是否为short类型 */
	public static boolean isShort(Class clazz)		{return (clazz.equals(short.class)||clazz.equals(Short.class));}
	/** 是否为int类型 */
	public static boolean isInt(Class clazz)		{return (clazz.equals(int.class)||clazz.equals(Integer.class));}
	/** 是否为long类型 */
	public static boolean isLong(Class clazz)		{return (clazz.equals(long.class)||clazz.equals(Long.class));}
	/** 是否为double类型 */
	public static boolean isDouble(Class clazz)		{return (clazz.equals(double.class)||clazz.equals(Double.class));}
	/** 是否为float类型 */
	public static boolean isFloat(Class clazz)		{return (clazz.equals(float.class)||clazz.equals(Float.class));}
	/** 是否为BigInteger类型 */
	public static boolean isBigInteger(Class clazz)	{return clazz.equals(BigInteger.class);}
	/** 是否为BigDecimal类型 */
	public static boolean isBigDecimal(Class clazz)	{return clazz.equals(BigDecimal.class);}
	//
	/** 是否为boolean类型 */
	public static boolean isBoolean(Class clazz)	{return (clazz.equals(boolean.class)||clazz.equals(Boolean.class));}
	/** 是否为data类型 */
	public static boolean isDate(Class clazz)		{return Date.class.isAssignableFrom(clazz);}
	/** 是否为Map类型 */
	public static boolean isMap(Class clazz)		{return Map.class.isAssignableFrom(clazz);}
	/** 是否为Collection类型 */
	public static boolean isCollection(Class clazz)	{return Collection.class.isAssignableFrom(clazz);}
	/** 是否为List类型 */
	public static boolean isList(Class clazz)		{return List.class.isAssignableFrom(clazz);}
	/** 是否为Set类型 */
	public static boolean isSet(Class clazz)		{return Set.class.isAssignableFrom(clazz);}
	/** 是否为Void类型 */
	public static boolean isVoid(Class clazz)		{return (clazz.equals(void.class)||clazz.equals(Void.class));}
	
	/**
	 * 去掉类路径前缀classpath:/
	 * @param path 路径
	 */
	public static String removePreClasspath(String path) {
		if (path == null) return null;
		if (path.indexOf("classpath:/") >= 0)
			path = path.trim().replaceAll("classpath:/", "");
		return path;
	}
	
	/**
	 * preADClasspath 添加类路径前缀 classpath:
	 * @param path 路径
	 */
	public static String addPreClasspath(String path) {
		if (path == null)
			path = "";
		if (path.indexOf("classpath:/") < 0)
			path = "classpath:/" + path.trim();
		return path;
	}
	
	/** 
	 * 是否为classptah
	 * @param path 路径
	 */
	public static boolean isClasspath(String path){
		return path.trim().startsWith("classpath:");
	}
	
	/**
	 * convertClasspath2Abspath<br>
	 * 类路径->绝对路径
	 * 例:classpath:/mmvc-config.xml 转换为 C:\WebRoot\WEB-INF\classes\mmvc-config.xml
	 * @param classPath 类路径
	 * @return 路径
	 */
	public static String classpath2Filepath(String classpath) {
		URL url = ClassUtils.class.getClassLoader().getResource(removePreClasspath(classpath));
		if (url == null) return null;
		return url.getPath();
	}
}
